﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Netfraction.Common.DataStorage;
using NetfractionHub.LocalMachine;
using NetfractionHub.LocalMachine.BotCommands;
using NetfractionHub.Network.Protocol;
using NetfractionHub.Network.Protocol.BASE.Factory;

namespace Netfraction.Hub.Bots.AnnouncerBot
{
    /// <summary>
    /// The AnnouncerBot is currently built into the hub's project file
    /// i.e. this seperate project is not in use.
    /// </summary>
    [BotNode(CommandPrefix="!")]
    public class AnnouncerBot : BotNode
    {
        private static DataSource _dataSource;
        private static SqlDataStore _sqlStore;

        public static SqlDataStore DataStore
        {
            get { return AnnouncerBot._sqlStore; }
            set { AnnouncerBot._sqlStore = value; }
        }

        
        public AnnouncerBot()
        {
            LoadHandlers();

            this.SessionHashAlgorithm = NetfractionHub.Network.Protocol.TIGR.Security.Cryptography.Tiger.Create();
            this.Identity.ClientId = NetfractionHub.Network.ConnectionManager.GenerateClientId(this, "the announcer bot private id");
            this.Identity.Description = "Release announcer";
            this.Identity.NodeType = NetfractionHub.IdentityNodeTypes.Bot;
            Version curVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
            this.Identity.ClientVersion = String.Format(System.Globalization.CultureInfo.InvariantCulture, "Netfraction Bot {0}.{1}", curVersion.Major, curVersion.Minor);
            this.Identity.MaximumUploadSpeed = 100 / 8 * 1024 * 1024;
            this.Identity.HubNormalCount = 1;
            this.SecurityIdentity = NetfractionHub.Security.Identity.CreateGenericIdentityForRole(NetfractionHub.Security.RoleManager.GetRoleById(6));
            this.Identity.Nickname = "Announcer";

            ConfigureDatabase();
            NetfractionHub.Network.ConnectionManager.OnClientConnected += new NetfractionHub.Network.ClientConnected(ConnectionManager_OnClientConnected);

            NetfractionHub.Network.ConnectionManager.SendNodeInformationToAll(this);
        }

        private void LoadHandlers()
        {
            AddCommand(new Handlers.ListReleases());
            AddCommand(new Handlers.ListCategories());
            AddCommand(new Handlers.AddCategory());
            AddCommand(new Handlers.AddRelease());
        }

        private void ConnectionManager_OnClientConnected(NetfractionHub.RemoteMachine.Node node)
        {
            this.HandleCommandMessage(node, "!listreleases \"5\"");
        }

        private static void ConfigureDatabase()
        {
            if (_dataSource == null)
            {
                CreateDataSource();
            }

            _sqlStore = new SqlDataStore(_dataSource, "releases.db");

            //Console.WriteLine(_sqlStore.ExecuteNonQuery("DROP TABLE Entries"));
            _sqlStore.ExecuteNonQuery("CREATE TABLE IF NOT EXISTS Entries (EntryId INTEGER PRIMARY KEY AUTOINCREMENT, AddedBy INTEGER, Date TEXT DEFAULT (CURRENT_DATE), Time TEXT DEFAULT (CURRENT_TIME), CategoryId INTEGER, Magnet TEXT)");
            _sqlStore.ExecuteNonQuery("CREATE TABLE IF NOT EXISTS Categories (CategoryId INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT)");
            _sqlStore.ExecuteNonQuery("CREATE TABLE IF NOT EXISTS Users (UserId INTEGER PRIMARY KEY AUTOINCREMENT, Username TEXT)");

            _sqlStore.Disconnect();
        }

        private static void CreateDataSource()
        {
            if (_dataSource != null)
            {
                return;
            }

            Version curVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;

            _dataSource = new DataSource();

            _dataSource.Name = "Announcer";
            _dataSource.Version = "0.1";
            _dataSource.Guid = new Guid("C67F1F5D-FB5A-437b-8719-067A903A984D");
            _dataSource.Author = "darkKlor";
            _dataSource.SourceLicence = "GPL v2.0";
            _dataSource.UpdateUrl = "";
            _dataSource.SiteUrl = "http://netfraction.codeplex.com/";
        }

        #region Singleton Pattern
        // Use singleton pattern.
        private static AnnouncerBot _instance;

        /// <summary>
        /// Obtain singleton instance of AnnouncerBot
        /// </summary>
        /// <returns></returns>
        public static AnnouncerBot GetInstance()
        {
            // Check instance
            if (AnnouncerBot._instance == null)
            {
                // Initialise instance
                AnnouncerBot._instance = new AnnouncerBot();
            }

            // Return instance
            return AnnouncerBot._instance;
        }
        #endregion Singleton Pattern

        public override void HandleCommandMessage(NetfractionHub.RemoteMachine.Node sourceNode, string message)
        {
            CommandMessage theCommand = ParseMessage(sourceNode, message);

            if (theCommand != null)
            {
                if (this.BotCommands.ContainsKey(theCommand.Name))
                {
                    this.BotCommands[theCommand.Name].HandleCommandMessage(sourceNode, theCommand);
                }
            }
            else
            {
                // unknown command
            }
        }

    }
}
